


class BufferFile:
    """helper class for async socket io
    
    Acts like a file, but stores data in memory
    for fast operation. Read bytes are removed from 
    stream. Size limit ensures that data is perserved."""
    
    def __init__(self,sz,data=""):
    
        self.max_size=sz
        self.data=data
        
        
    def read(self,size=None):
        """reads data and removes from buffer"
        
        Omission of the size argument returns all
        the data."""
        
        outdata=self.data[0:size]
        
        if not size== None:
            self.data=data[size:]
            
        else:
            self.data=""
    
        return outdata
        
    
    def readline(self):
        """Reads a line of data and removes from buffer.
		
		Returns a bool indicating if a line was found, and then
		the contents of the found line."""
        
        if "\n" in self.data:
            i=self.data.index("\n") #index of end of line in file
            
        elif "\r" in self.data:
                i = self.data.index("\r")
            
        else: return False, "" #return nothing if there is not
                               #yet a full line in the file
        
        if(i>0 and self.data[i-1]=="\r"): #don't include trailing CR
            outdata=self.data[0:i-1]
            
        else:
            outdata=self.data[0:i]
            
        self.data=self.data[i+1:]
        return True, outdata
        
        
    def readto(self,delim):
        """Read up to the delimiter.
        
            Remove data including delimiter from buffer"""
        
        if delim in self.data:
            i=self.data.index(delim)
            out= self.data[0:i]
            self.data=self.data[i+len(delim):]
            found=True
            
        else:
            out= ""
            found=False
            
        return found, out
        
        
    def sendtosock(self,soc,sz):
        """sends as much data as possible to a socket"""
        
        data_sent=soc.send(self.data[:sz])
        print("sending:\n"+self.data[:data_sent])
        self.data=self.data[data_sent:]
        print("sent %s bytes from file; % remaining" %(data_sent,len(self.data)))
        
    def write(self,newdata):
        """writes as much data as possible
        
        returns number of bytes actually written"""
    
        space=self.max_size-len(self.data)
    
        if len(newdata)<=space:
            self.data+=newdata
            return len(newdata)
            
        else:
            self.data+=newdata[:space]
            return space
            
            
    def readfrom(self,file):
        """ Reads as much as possible from the file.
        
            Returns True if it read all remaining data in the file. """
            
        space=self.max_size-len(self.data)
        newdata=file.read(space)
        self.data+=newdata
        
        return len(newdata)<space
        
    
    def close(self):
        """how do u close a str? lulz"""
        pass #self.data=""